package com.twu.biblioteca;

import java.io.PrintStream;

public class BibliotecaAppBuilder {

    private UserRepository userRepository;
    private MovieRepository movieRepository;
    private UserInterface userInterface;
    private MenuController menuController;
    private BookRepository bookRepository;
    private ReserveController reserveController;
    private SecurityContext securityContext;
    private BookManager bookManager;
    private ControllerManager controllerManager;
    private LoginController loginController;
    private BibliotecaApp bibliotecaApp;

    private PrintStream out() {
        return System.out;
    }

    private UserInterface userInterface() {
        if (userInterface == null) {
            userInterface = new UserInterface(out());
        }
        return userInterface;
    }

    private UserRepository userRepository() {
        if (userRepository == null) {
            userRepository = new UserRepository();
            User user = new User("user");
            user.setPassword("pass");
            userRepository.add(user);
        }
        return userRepository;
    }

    private MovieRepository movieRepository() {
        if (movieRepository == null) {
            movieRepository = new MovieRepository();
        }
        return movieRepository;
    }

    private MenuController menuController() {
        if (menuController == null) {
            menuController = new MenuController(userInterface(), bookRepository(), movieRepository());
            menuController.setLoginController(loginController());
            menuController.setReserveController(reserveController());
            menuController.setSecurityContext(securityContext());
        }
        return menuController;
    }

    private BookRepository bookRepository() {
        if (bookRepository == null) {
            bookRepository = new BookRepository();
            bookRepository.add("Test-Driven Development");
            bookRepository.add("REST in Practice");
        }
        return bookRepository;
    }

    private ReserveController reserveController() {
        if (reserveController == null) {
            reserveController = new ReserveController();
            reserveController.setUserInterface(userInterface());
            reserveController.setBookManager(bookManager());
        }
        return reserveController;
    }

    private LoginController loginController() {
        if (loginController == null) {
            loginController = new LoginController();
            loginController.setUserInterface(userInterface());
            loginController.setUserRepository(userRepository());
            loginController.setSecurityContext(securityContext());
        }
        return loginController;
    }

    private SecurityContext securityContext() {
        if (securityContext == null) {
            securityContext = new SecurityContext();
        }
        return securityContext;
    }

    private BookManager bookManager() {
        if (bookManager == null) {
            bookManager = new BookManager(bookRepository());
        }
        return bookManager;
    }

    private ControllerManager controllerManager() {
        if (controllerManager == null) {
            controllerManager = new ControllerManager(menuController());
        }
        return controllerManager;
    }

    private InputDispatcher inputDispatcher() {
        return new InputDispatcher(System.in, controllerManager());
    }

    BibliotecaApp bibliotecaApp() {
        if (bibliotecaApp == null) {
            bibliotecaApp = new BibliotecaApp(userInterface(), inputDispatcher(), bookRepository(), movieRepository(), controllerManager(), userRepository());
        }
        return bibliotecaApp;
    }

}
